package com.gmall.gateway.exception;

import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.web.reactive.function.server.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @author HL.Wu
 * @date 2020/7/2 17:12
 * Copyright ©https://blog.csdn.net/qq_31150503 Copyright@2009-2020 AII Right Reserve
 */
public class ExceptionHandler extends DefaultErrorWebExceptionHandler {
    /**
     * Create a new {@code DefaultErrorWebExceptionHandler} instance.
     *
     * @param errorAttributes    the error attributes
     * @param resourceProperties the resources configuration properties
     * @param errorProperties    the error configuration properties
     * @param applicationContext the current application context
     */
    public ExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties, ErrorProperties errorProperties, ApplicationContext applicationContext) {
        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
    }

    /**
     * Get the HTTP error status information from the error map.
     *
     * @param errorAttributes the current error information
     * @return the error HTTP status
     */
    @Override
    protected int getHttpStatus(Map<String, Object> errorAttributes) {
        return (int) errorAttributes.get("code");
    }

    @Override
    protected Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> errorAttributes = super.getErrorAttributes(request, options);
        int code = (int)errorAttributes.get("status");
        errorAttributes.put("code", code);
        Throwable error = super.getError(request);
        // 异常信息处理
        String errorMessage = exceptionMessageHandle(request,error);
        map.put("code",code);
        map.put("message","呀！服务一不小心走丢失了，请稍后再试");
        map.put("info",errorMessage);
        map.put("data",null);
        return map;
    }

    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }

    /**
     * 异常信息进行拼接处理返回
     *
     * @param request
     * @param exception
     * @return
     */
    public String exceptionMessageHandle(ServerRequest request,Throwable exception){
        StringBuffer sb = new StringBuffer("【");
        exception.getMessage();
        sb.append(request.method()).append("   ").append(request.uri().getPath());
        if(exception != null){
            sb.append("    ").append(exception.getMessage());
        }
        sb.append("】");
        return sb.toString();
    }
}
